package com.sz.biz.trade.bill.service.impl;

import com.google.common.collect.Lists;
import com.sz.biz.trade.bill.entity.TrdBillingTask;
import com.sz.biz.common.AbstractVersionEntityService;
import com.sz.biz.trade.bill.service.TrdBillingOrderRelService;
import com.sz.biz.trade.bill.service.TrdBillingService;
import com.sz.biz.trade.bill.service.TrdBillingTaskService;
import com.sz.biz.trade.bill.dto.TrdBillingDetailDto;
import com.sz.biz.trade.bill.dto.TrdBillingGenerateDto;
import com.sz.biz.trade.bill.dto.TrdBillingTaskDto;
import com.sz.biz.trade.bill.dto.TrdBillingTaskQueryDto;
import com.sz.biz.trade.ord.service.TrdOrderService;
import com.sz.common.base.dao.ParamData;
import com.sz.common.base.dto.CommonModel;
import com.sz.common.base.dto.QResultDto;
import com.sz.common.base.dto.QueryParams;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.utils.DateUtils;
import com.sz.biz.logistics.constants.ErrorCodes;
import com.sz.biz.logistics.bill.entity.BillingTaskStatus;
import com.sz.common.core.service.PrincipalUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * Function: 账单任务服务<br>
 * Author: changwentao <br>
 * Date: 2017-07-18 14:10:00
 */
@Service("trdBillingTaskService")
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class TrdBillingTaskServiceImpl extends AbstractVersionEntityService implements TrdBillingTaskService {

    @Autowired
    private TrdBillingService trdBillingService;
    @Autowired
    private TrdBillingOrderRelService trdBillingOrderRelService;
    @Autowired
    private TrdOrderService trdOrderService;

    /**
     * 根据任务编码删除任务
     *
     * @param taskCodes taskCodes
     */
    @Override
    public void batchdeleteByTaskCode(List<String> taskCodes) {
        ParamData paramData = new ParamData();
        paramData.put("taskCodes", taskCodes);
        //只能删除已完成状态的任务
        checkSatusPreDelete(paramData);
        dao.update(getSqlName("batchdeleteByTaskCode"), paramData);
    }

    /**
     * 只能删除已完成的任务
     *
     * @param paramData paramData
     */
    private void checkSatusPreDelete(ParamData paramData) {
        List<TrdBillingTask> billingTasks = dao.findForList(getSqlName("findByTaskCodes"), paramData, TrdBillingTask.class);
        if (null != billingTasks && billingTasks.size() > 0) {
            for (TrdBillingTask billingTask : billingTasks) {
                if (!BillingTaskStatus.COMPLETED.getCode().equals(billingTask.getTaskStatus().toString())) {
                    throw Exceptions.bizException(ErrorCodes.ERROR_FINANCIAL_COMPLETE_CAN_DELETE);
                }
            }
        }
    }

    /**
     * 生成账单
     *
     * @param type                type
     * @param billingTaskQueryDto billingTaskQueryDto
     */
    @Override
    public String generateBill(int type, TrdBillingTaskQueryDto billingTaskQueryDto) {
        billingTaskQueryDto.setType(type);
        //任务编码
        String taskCode = generateTaskCode(type);
        //任务开始时间
        Date taskStartTime = dao.getDbDate();
        //获取(用户)时间段内的 订单数
        Integer countGenerateBillings = trdOrderService.countGenerateBillings(type, billingTaskQueryDto.getBizCompanyIds(),
                billingTaskQueryDto.getPlatformIds(),
                billingTaskQueryDto.getStartEffectTime(), billingTaskQueryDto.getEndEffectTime());
        if (null != countGenerateBillings && countGenerateBillings > 0) {
            //创建一个线程池
            ExecutorService cachedThreadPool = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                    60L, TimeUnit.SECONDS,
                    new SynchronousQueue<Runnable>());

            cachedThreadPool.execute(() -> {
                List<String> taskCodes = null;
                try {
                    taskCodes = generateBillThread(billingTaskQueryDto, taskCode, taskStartTime);
                    if (null != taskCodes && taskCodes.size() > 0) {
                        //所有账单生成完毕，任务更新为完成状态
                        updateTaskStatus(BillingTaskStatus.COMPLETED, taskCodes);
                    }
                } catch (Exception e) {
                    if (null != taskCodes && taskCodes.size() > 0) {
                        //所有账单生成完毕，任务更新为完成状态
                        updateTaskStatus(BillingTaskStatus.SUSPEND, taskCodes);
                        deleteBillingAndOrder(taskCodes);
                    }
                    e.printStackTrace();
                }
            });

        } else {
            //所选时间段内没有订单
            throw Exceptions.bizException(ErrorCodes.ERROR_FINANCIAL_GENERATE_ORDER_NOT_EXIST);
        }
        return taskCode;
    }


    /**
     * 删除任务下账单和订单
     *
     * @param taskCodes taskCodes
     */
    private void deleteBillingAndOrder(List<String> taskCodes) {
        //删除任务下的所有账单
        trdBillingService.batchDeleteByTaskCodes(taskCodes);

        TrdBillingTask trdBillingTask = findByTaskCode(taskCodes.get(0));
        //删除账单下所有订单关联
        if (trdBillingTask != null) {
            trdBillingOrderRelService.batchDeleteByTaskCodes(taskCodes, trdBillingTask.getType());
        }
    }

    /**
     * 生成账单操作
     *
     * @param trdBillingTaskQueryDto trdBillingTaskQueryDto
     */
    private List<String> generateBillThread(TrdBillingTaskQueryDto trdBillingTaskQueryDto, String taskCode, Date taskStartTime) {
        List<String> taskCodes = new ArrayList<>();
        taskCodes.add(taskCode);
        try {
            List<Integer> bizCompanyIdsList = trdBillingTaskQueryDto.getBizCompanyIds();
            List<Integer> platformIdList = trdBillingTaskQueryDto.getPlatformIds();
            int type = trdBillingTaskQueryDto.getType();
            Date startEffectTime = trdBillingTaskQueryDto.getStartEffectTime();
            Date endEffectTime = trdBillingTaskQueryDto.getEndEffectTime();
            List<TrdBillingGenerateDto> ordServiceBillList =
                    populateOrderList(type, bizCompanyIdsList, platformIdList, startEffectTime, endEffectTime);
            List<TrdBillingGenerateDto> ordServiceBillListGenerated =
                    populateOrderListGenerated(type, bizCompanyIdsList, platformIdList, startEffectTime, endEffectTime);
            //保存任务
            saveTask(taskCode, taskStartTime, trdBillingTaskQueryDto, bizCompanyIdsList, platformIdList, ordServiceBillList, ordServiceBillListGenerated);
            //计算账单
            trdBillingTaskQueryDto.setTaskCode(taskCode);
            generateBillOperation(trdBillingTaskQueryDto);

        } catch (Exception e) {
            updateBillingTask(taskCode);
            deleteBillingAndOrder(taskCodes);
            taskCodes = null;
            e.printStackTrace();
        }
        return taskCodes;
    }

    /**
     * 更新任务订单数量和客户数量
     *
     * @param taskCode taskCode
     */
    private void updateBillingTask(String taskCode) {
        TrdBillingTask billingTask = findByTaskCode(taskCode);
        if (null != billingTask) {
            Date now = dao.getDbDate();
            billingTask.setOrderQty(0);
            billingTask.setCompleteOrderQty(0);
            billingTask.setSkippedOrderQty(0);
            billingTask.setCompleteOrderQty(0);
            billingTask.setCompleteBizCompanyQty(0);
            billingTask.setSkippedBizCompanyQty(0);
            billingTask.setTaskStatus(Integer.parseInt(BillingTaskStatus.SUSPEND.getCode()));
            billingTask.setTaskEndTime(now);
            updateBillingTask(billingTask);
        }
    }

    /**
     * 任务异常，修改任务状态
     *
     * @param taskStatus taskStatus
     * @param taskCodes  taskCodes
     */
    @Override
    public void updateTaskStatus(BillingTaskStatus taskStatus, List<String> taskCodes) {
        Date now = dao.getDbDate();
        ParamData paramData = new ParamData();
        paramData.put("taskEndTime", now);
        paramData.put("taskStatus", taskStatus.getCode());
        paramData.put("taskCodes", taskCodes);
        dao.update(getSqlName("updateTaskStatus"), paramData);
    }

    /**
     * 账单任务详情
     *
     * @param taskCode taskCode
     */
    @Override
    public TrdBillingDetailDto billingTaskDetail(String taskCode) {
        return (TrdBillingDetailDto) dao.findForObject(getSqlName("billingTaskDetail"), taskCode);
    }

    /**
     * 修改已经生成账单的客户数量和订单数量
     *
     * @param taskCode              taskCode
     * @param completeOrderQuantity completeOrderQuantity
     */
    @Override
    public void updateTaskCustomerComplete(String taskCode, Integer completeOrderQuantity) {
        TrdBillingTask billingTask = findByTaskCode(taskCode);
        if (null != billingTask) {
            Integer completeCustomers = billingTask.getCompleteBizCompanyQty() == null ? Integer.valueOf(0) : billingTask.getCompleteBizCompanyQty();
            Integer completeOrders = billingTask.getCompleteOrderQty() == null ? Integer.valueOf(0) : billingTask.getCompleteOrderQty();
            billingTask.setCompleteBizCompanyQty(completeCustomers + 1);
            billingTask.setCompleteOrderQty(completeOrders + completeOrderQuantity);
            dao.update(getSqlName("updateSelective"), billingTask);
        }
    }

    /**
     * 保存任务
     *
     * @param taskCode                    taskCode
     * @param taskStartTime               taskStartTime
     * @param billingTaskQueryDto         billingTaskQueryDto
     * @param customerIdList              customerIdList
     * @param platformIdList              platformIdList
     * @param ordServiceBillList          ordServiceBillList
     * @param ordServiceBillListGenerated ordServiceBillListGenerated
     * @return String
     */
    private String saveTask(String taskCode, Date taskStartTime, TrdBillingTaskQueryDto billingTaskQueryDto,
                            List<Integer> customerIdList, List<Integer> platformIdList, List<TrdBillingGenerateDto> ordServiceBillList,
                            List<TrdBillingGenerateDto> ordServiceBillListGenerated) {
        //保存任务
        TrdBillingTask billingTask = new TrdBillingTask();
        if (null != customerIdList && customerIdList.size() > 0) {
            billingTask.setBizCompanyIds(StringUtils.join(customerIdList, ","));
        }
        if (null != platformIdList && platformIdList.size() > 0) {
            billingTask.setPlatformIds(StringUtils.join(platformIdList, ","));
        }
        billingTask.setIsDeleted(false);
        if (null != ordServiceBillList) {
            billingTask.setOrderQty(ordServiceBillList.size());
            if (null != ordServiceBillListGenerated) {
                billingTask.setOrderQty(ordServiceBillList.size() + ordServiceBillListGenerated.size());
            }
        }
        if (null != customerIdList && customerIdList.size() > 0) {
            billingTask.setBizCompanyQty(customerIdList.size());
        } else {
            billingTask.setBizCompanyQty(countCustomers(ordServiceBillList));
        }
        billingTask.setTaskCode(taskCode);
        billingTask.setTaskStartTime(taskStartTime);
        billingTask.setOrderStartTime(billingTaskQueryDto.getStartEffectTime());
        billingTask.setOrderEndTime(billingTaskQueryDto.getEndEffectTime());
        billingTask.setIsRegenerate(false);
        billingTask.setTaskStatus(Integer.parseInt(BillingTaskStatus.PROCESSING.getCode()));
        billingTask.setRegenerateTimes(0);
        billingTask.setType(billingTaskQueryDto.getType());
        billingTask.setCreateUserId(PrincipalUtils.getAccountId());
        billingTask.setLastUpdateUserId(PrincipalUtils.getAccountId());
        dao.save(getSqlName("insertSelective"), billingTask);
        return taskCode;
    }

    /**
     * 生成任务编码-type==1?"PAY":"RECE"+年月日各两位+当日三位流水
     *
     * @return String
     */
    private synchronized String generateTaskCode(int type) {
        //数据库当前时间
        Date now = dao.getDbDate();
        //年月日各两位
        String prefix = (type == 1 ? "RECE" : "PAY") + DateUtils.formatDateForBillingTaskCode(now);
        //最三位流水
        String suffix = "001";
        //获取数据库最新
        String lastTaskCode = getLastTaskCode(prefix);
        if (!StringUtils.isEmpty(lastTaskCode)) {
            suffix = lastTaskCode.substring(prefix.length());
            suffix = populateSuffix(suffix, 3);
        }
        String newTaskCod = prefix + suffix;
        //新的任务编码是否已经存在
        String newTaskCodeIsExist = getLastTaskCode(newTaskCod);
        if (!StringUtils.isEmpty(newTaskCodeIsExist)) {
            generateTaskCode(type);
        }
        return prefix + suffix;
    }

    /**
     * 不够位数的在前面补0，保留num的长度位数字
     *
     * @param code code
     * @return String
     */
    private static String populateSuffix(String code, int num) {
        return String.format("%0" + num + "d", Integer.parseInt(code) + 1);
    }

    /**
     * 数据库当天最新任务编码
     *
     * @param prefix prefix
     * @return String
     */
    private String getLastTaskCode(String prefix) {
        ParamData paramData = new ParamData();
        paramData.put("prefix", prefix);
        return (String) dao.findForObject(getSqlName("getLastTaskCode"), paramData);
    }

    /**
     * 生成具体账单
     *
     * @param billingTaskQueryDto billingTaskQueryDto
     */
    private void generateBillOperation(TrdBillingTaskQueryDto billingTaskQueryDto) {

        trdBillingService.generateBill(billingTaskQueryDto);
    }

    /**
     * 计算要生成的账单中的客户数量
     *
     * @param ordServiceBillList ordServiceBillList
     */
    private Integer countCustomers(List<TrdBillingGenerateDto> ordServiceBillList) {
        Set<Integer> customers = new HashSet<>();
        if (null != ordServiceBillList && ordServiceBillList.size() > 0) {
            customers.addAll(ordServiceBillList.stream().map(TrdBillingGenerateDto::getBizCompanyId).collect(Collectors.toList()));
        }
        return customers.size();
    }

    /**
     * 重新生成账单
     *
     * @param taskCodes taskCodes
     */
    @Override
    public void regenerate(List<String> taskCodes) {
        //正在任务列表或者草稿之后状态的账单都不能生成
        checkTaskStatusPreDelete(taskCodes);

        //删除账单下所有订单关联
        TrdBillingTask trdBillingTask = findByTaskCode(taskCodes.get(0));
        trdBillingOrderRelService.batchDeleteByTaskCodesDraft(taskCodes, trdBillingTask.getType());
        //删除任务下的所有账单
        trdBillingService.batchDeleteByTaskCodes(taskCodes);
        //修改任务状态
        updateTaskStatusByTaskCodes(taskCodes);
        //创建一个线程池
        ExecutorService cachedThreadPool = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                        60L, TimeUnit.SECONDS,
                        new SynchronousQueue<Runnable>());

        cachedThreadPool.execute(() -> {
            try {
                regenerateBillThread(taskCodes);
                //所有账单生成完毕，任务更新为完成状态
                updateTaskStatus(BillingTaskStatus.COMPLETED, taskCodes);
            } catch (Exception e) {
                //所有账单生成完毕，任务更新为完成状态
                updateTaskStatus(BillingTaskStatus.SUSPEND, taskCodes);
                deleteBillingAndOrder(taskCodes);
                e.printStackTrace();
            }
        });
    }

    /**
     * 重新生成账单
     *
     * @param taskCodes taskCodes
     */
    private void regenerateBillThread(List<String> taskCodes) {
        try {
            //获取任务中的客户，账单周期时间
            List<TrdBillingTask> billingTaskList = findByTaskCodes(taskCodes);
            if (null != billingTaskList && billingTaskList.size() > 0) {
                for (TrdBillingTask billingTask : billingTaskList) {
                    String bizCompanyIdsStr = billingTask.getBizCompanyIds();
                    String platformIdsStr = billingTask.getPlatformIds();


                    List<Integer> bizCompanyIdList = new ArrayList<>();
                    if (bizCompanyIdsStr != null && !"".equals(bizCompanyIdsStr)) {
                        String[] bizCompanyIds = bizCompanyIdsStr.split(",");
                        for (String bizCompanyId : bizCompanyIds) {
                            bizCompanyIdList.add(Integer.parseInt(bizCompanyId));
                        }
                    }
                    List<Integer> platformIdList = new ArrayList<>();
                    if (platformIdsStr != null && !"".equals(platformIdsStr)) {
                        String[] platformIds = platformIdsStr.split(",");
                        for (String platformId : platformIds) {
                            platformIdList.add(Integer.parseInt(platformId));
                        }
                    }

                    TrdBillingTaskQueryDto trdBillingTaskQueryDto = new TrdBillingTaskQueryDto();

                    trdBillingTaskQueryDto.setTaskCode(billingTask.getTaskCode());
                    trdBillingTaskQueryDto.setType(billingTask.getType());
                    trdBillingTaskQueryDto.setBizCompanyIds(bizCompanyIdList);
                    trdBillingTaskQueryDto.setPlatformIds(platformIdList);
                    trdBillingTaskQueryDto.setStartEffectTime(billingTask.getOrderStartTime());
                    trdBillingTaskQueryDto.setEndEffectTime(billingTask.getOrderEndTime());
                    trdBillingService.regenerate(trdBillingTaskQueryDto);
                }
            }
        } catch (Exception e) {
            updateTaskStatus(BillingTaskStatus.SUSPEND, taskCodes);
            deleteBillingAndOrder(taskCodes);
        }
    }

    /**
     * 重新生成时更新任务状态
     *
     * @param taskCodes taskCodes
     */
    private void updateTaskStatusByTaskCodes(List<String> taskCodes) {
        if (null != taskCodes && taskCodes.size() > 0) {
            for (String taskCode : taskCodes) {
                TrdBillingTask billingTask = findByTaskCode(taskCode);
                if (null != billingTask) {
                    Integer type = billingTask.getType();
                    String bizCompanyIdsStr = billingTask.getBizCompanyIds();
                    String platformIdsStr = billingTask.getPlatformIds();

                    List<Integer> bizCompanyIdList = new ArrayList<>();
                    if (bizCompanyIdsStr != null && !"".equals(bizCompanyIdsStr)) {
                        String[] bizCompanyIds = bizCompanyIdsStr.split(",");
                        for (String bizCompanyId : bizCompanyIds) {
                            bizCompanyIdList.add(Integer.parseInt(bizCompanyId));
                        }
                    }
                    List<Integer> platformIdList = new ArrayList<>();
                    if (platformIdsStr != null && !"".equals(platformIdsStr)) {
                        String[] platformIds = platformIdsStr.split(",");
                        for (String platformId : platformIds) {
                            platformIdList.add(Integer.parseInt(platformId));
                        }
                    }
                    List<TrdBillingGenerateDto> ordServiceBillList =
                            populateOrderList(type, bizCompanyIdList, platformIdList,
                                    billingTask.getOrderStartTime(), billingTask.getOrderEndTime());
                    List<TrdBillingGenerateDto> ordServiceBillListGenerated =
                            populateOrderListGenerated(type, bizCompanyIdList, platformIdList,
                                    billingTask.getOrderStartTime(), billingTask.getOrderEndTime());
                    //更新任务数据
                    updateReTaskForReGenerate(taskCode, bizCompanyIdList, platformIdList, ordServiceBillList, ordServiceBillListGenerated);
                }

            }
        }
    }

    /**
     * 未生账单列表
     *
     * @param type            type
     * @param customerIdList  customerIdList
     * @param startEffectTime startEffectTime
     * @param endEffectTime   endEffectTime
     * @return List
     */
    private List<TrdBillingGenerateDto> populateOrderList(int type,
                                                          List<Integer> customerIdList, List<Integer> platformIdList,
                                                          Date startEffectTime, Date endEffectTime) {
        return trdOrderService.getOrderByCreatBillQuery(type, customerIdList, platformIdList, startEffectTime, endEffectTime, false);
    }

    /**
     * 已经生账单列表
     *
     * @param type            type
     * @param customerIdList  customerIdList
     * @param platformIdList  platformIdList
     * @param startEffectTime startEffectTime
     * @param endEffectTime   endEffectTime
     * @return List
     */
    private List<TrdBillingGenerateDto> populateOrderListGenerated(int type, List<Integer> customerIdList,
                                                                   List<Integer> platformIdList,
                                                                   Date startEffectTime, Date endEffectTime) {
        return trdOrderService.getOrderByCreatBillQuery(type, customerIdList, platformIdList, startEffectTime, endEffectTime, true);
    }


    /**
     * 更新任务数据
     *
     * @param taskCode           taskCode
     * @param bizCompanyIdList   bizCompanyIdList
     * @param platformIdList     platformIdList
     * @param ordServiceBillList ordServiceBillList
     */
    private void updateReTaskForReGenerate(String taskCode, List<Integer> bizCompanyIdList, List<Integer> platformIdList,
                                           List<TrdBillingGenerateDto> ordServiceBillList,
                                           List<TrdBillingGenerateDto> ordServiceBillListGenerated) {
        //任务开始时间
        Date taskStartTime = dao.getDbDate();
        TrdBillingTask billingTask = new TrdBillingTask();
        billingTask.setTaskCode(taskCode);
        billingTask.setTaskStatus(Integer.parseInt(BillingTaskStatus.PROCESSING.getCode()));
        billingTask.setTaskStartTime(taskStartTime);
        billingTask.setBizCompanyQty(null == bizCompanyIdList ? 0 : bizCompanyIdList.size());

        billingTask.setCompleteBizCompanyQty(0);//完成公司数
        billingTask.setSkippedBizCompanyQty(0);//跳过公司数
        billingTask.setSkippedOrderQty(0); //跳过订单数
        billingTask.setCompleteOrderQty(0); //完成订单数

        billingTask.setLastUpdateUserId(PrincipalUtils.getAccountId());
        if (null != ordServiceBillList) {
            billingTask.setOrderQty(ordServiceBillList.size());
            if (null != ordServiceBillListGenerated) {
                billingTask.setOrderQty(ordServiceBillList.size() + ordServiceBillListGenerated.size());
            }
        } else {
            billingTask.setOrderQty(0);
        }
        if (null != bizCompanyIdList && bizCompanyIdList.size() > 0) {
            billingTask.setBizCompanyQty(bizCompanyIdList.size());
        } else {
            billingTask.setBizCompanyQty(countCustomers(ordServiceBillList));
        }
        dao.update(getSqlName("updateTaskStatusForRegenerate"), billingTask);
    }

    /**
     * 正在任务列表或者草稿之后状态的账单都不能生成
     *
     * @param taskCodes taskCodes
     */
    private void checkTaskStatusPreDelete(List<String> taskCodes) {
        List<TrdBillingTask> billingTasks = findByTaskCodes(taskCodes);
        for (TrdBillingTask billingTask : billingTasks) {
            //正在任务列表或者草稿之后状态的账单都不能生成
            if (!billingTask.getTaskStatus().equals(Integer.parseInt(BillingTaskStatus.SUSPEND.getCode()))) {
                throw Exceptions.bizException(ErrorCodes.ERROR_FINANCIAL_SUSPEND_CAN_REGENERATE);
            }
        }
    }

    /**
     * 根据任务编码获取任务
     *
     * @param taskCodes taskCode
     * @return List
     */
    @Override
    public List<TrdBillingTask> findByTaskCodes(List<String> taskCodes) {
        ParamData paramData = new ParamData();
        paramData.put("taskCodes", taskCodes);
        return dao.findForList(getSqlName("findByTaskCodes"), paramData, TrdBillingTask.class);
    }

    /**
     * 根据任务编码获取任务
     *
     * @param taskCode taskCode
     * @return TrdBillingTask
     */
    @Override
    public TrdBillingTask findByTaskCode(String taskCode) {
        return (TrdBillingTask) dao.findForObject(getSqlName("findByTaskCode"), taskCode);
    }

    /**
     * 账单任务列表
     *
     * @param params params
     * @return QResultDto
     */
    @Override
    public QResultDto findBillingTaskList(QueryParams params) {
        ParamData pd = convertQueryParams(params);
        //根据条件获取账单列表
        List<TrdBillingTaskDto> billTasks = dao.findForList(getSqlName("findTaskByFilterListPage"), pd, TrdBillingTaskDto.class);
        return new QResultDto(billTasks, pd.getPagination());
    }

    /**
     * 所有账单任务状态
     *
     * @return 顺序： 处理中；已完成；异常
     */
    @Override
    public List<CommonModel> getAllTaskStatus() {
        List<CommonModel> list = Lists.newArrayList();
        for (BillingTaskStatus billingTaskStatus : BillingTaskStatus.values()) {
            CommonModel dto = new CommonModel(billingTaskStatus.name(), billingTaskStatus.getName());
            list.add(dto);
        }
        return list;
    }

    /**
     * 更新账单任务
     *
     * @param billingTask billingTask
     */
    @Override
    public void updateBillingTask(TrdBillingTask billingTask) {
        dao.update(getSqlName("updateSelective"), billingTask);
    }

    @Override
    protected String getMapperNamespace() {
        return "TrdBillingTaskMapper";
    }
}
